home *** CD-ROM | disk | FTP | other *** search
- ;* OBJHASH.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Support for Obj-hash & unhash *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- DATASEG
- obj_cntr DW 1
-
- CODESEG
- ;************************************************************************
- ;* Object Hash *
- ;************************************************************************
- PROC C objhash USES si di, @@reg:WORD
- LOCAL @@cntr:REG
-
- cmp [obj_hlist.page], 0 ; anyone home ?
- je @@notfound
-
- mov bx, [@@reg]
- mov ax, [(REG bx).disp]
- mov dx, [(REG bx).page]
- mov bl, [obj_hlist.page]
- mov bh, 0
- ldpage es, bx
- mov si, [obj_hlist.disp]
- call lookup ; search the a-list
- cmp bl, 0
- je @@notfound
-
- mov ax, [(LISTDEF es:di).cdr.disp] ; load the hash counter
- jmp @@ret
-
- @@notfound: ; make a new entry
- mov ax, [obj_cntr] ; load obj hash counter
- push ax
- inc [obj_cntr]
- mov [tmp_reg.page], SPECFIX*2 ; convert hash counter to a fixnum
- mov [tmp_reg.disp], ax
- mov ax, [@@reg]
- lea cx, [tmp_reg]
- call cons C, cx, ax, cx ; tmp_reg = (object . hash-counter)
- lea bx, [nil_reg]
- lea cx, [tmp_reg]
- call cons C, cx, cx, bx ; tmp_reg = ((obj . hash))
- mov bx, [tmp_reg.page] ; load pointer to newest list cell
- mov ax, [tmp_reg.disp]
- ldpage es, bx
- mov si, ax ; newly created list in [es:si]
- xchg [obj_hlist.page], bl ; header <-> pointer to list cell
- xchg [obj_hlist.disp], ax
- mov [(LISTDEF es:si).cdr.page], bl ; (set-cdr! list-cell chain-header)
- mov [(LISTDEF es:si).cdr.disp], ax
- pop ax ; restore the counter
- @@ret:
- mov bx, [@@reg] ; load destination register's address
- mov [(REG bx).page], SPECFIX*2
- mov [(REG bx).disp], ax
- ret
- ENDP objhash
-
- PROC C objunhash USES si, @@reg:WORD
- mov si, [@@reg]
- mov bx, [(REG si).page]
- cmp bl, SPECFIX*2
- je @@maybe
- @@definitelynot:
- xor ax, ax ; load nil
- xor dl, dl
- jmp @@wipeout
- @@maybe:
- mov ax, [(REG si).disp]
- cmp ax, [obj_cntr] ; test against next available counter value
- jae @@definitelynot ; hash index too large? if so, jump
- lea di, [obj_hlist]
- push ds
- pop es ; [es:di] is the chain of objects
- jmp @@inloop
- @@next:
- pop es
- lea di, [(LISTDEF es:di).cdr] ; follow the chain (cdr linked)
- @@inloop:
- mov bl, [(POINTER es:di).page]
- mov di, [(POINTER es:di).disp]
- cmp bl, NIL_PAGE*2 ; end of chain?
- je @@definitelynot
- ldpage es, bx
- push es ; we'll maybe need to back up
- mov bl, [(LISTDEF es:di).car.page]
- mov si, [(LISTDEF es:di).car.disp]
- ldpage es, bx ; now [es:si] is a pair.
- cmp [(LISTDEF es:si).cdr.disp], ax ; is it our number?
- jne @@next
- pop ax ; cleanup the stack
- mov ax, [(POINTER es:si).disp]
- mov dl, [(POINTER es:si).page]
- @@wipeout:
- mov di, [@@reg]
- mov [(REG di).disp], ax
- mov [(REG di).bpage], dl
- ret
- ENDP objunhash
-
- ;************************************************************************
- ;* Object Hash Table Garbage Collection *
- ;************************************************************************
- PROC C gc_oht USES si di
- LOCAL $$pair:REG, $$current:REG, $$previous:REG
-
- lea si, [obj_hlist]
- push ds
- pop es
- call colnext
- ret
-
- ;************************************************************************
- ;* Local Support for Object Hash Table Garbage Collection *
- ;************************************************************************
- PROC NOLANGUAGE colnext near
- DATASEG
- @@table DW @@list ; [0] List cells
- DW @@mark ; [1] Fixnums
- DW @@var ; [2] Flonums
- DW @@var ; [3] Bignums
- DW @@var ; [4] Symbols
- DW @@var ; [5] Strings
- DW @@var ; [6] Arrays
- DW @@var ; [7] Continuations
- DW @@var ; [8] Closures
- DW @@mark ; [9] Free page
- DW @@var ; [10] Code block
- DW @@var ; [11] Inline code
- DW @@var ; [12] Port data objects
- DW @@mark ; [13] Characters
- DW @@var ; [14] Environments
- CODESEG
- mov [$$previous.page], 0
- mov [$$previous.disp], si
- @@loop:
- xor bx, bx
- mov bl, [(LISTDEF es:si).car.page]
- or bl, bl ; does entry exist?
- jnz @@ok
- ret
- @@ok:
- mov di, [(LISTDEF es:si).car.disp] ; compute and save pointer to current cell
- ldpage es, bx
- mov [$$current.page], bx
- mov [$$current.disp], di
- mov bl, [(LISTDEF es:di).car.page] ; compute and save pointer to object/hash-key pair
- mov si, [(LISTDEF es:di).car.disp]
- test bl, GC_BIT ; is current cell marked as referenced?
- jz @@doitnow
- jmp @@skip
- @@doitnow: ; if marked, GC during OBJECT-HASH
- ldpage es, bx
- mov [$$pair.page], bx
- mov [$$pair.disp], si ; see what object pointer points to
- mov bl, [(LISTDEF es:si).car.page]
- cmp bl, DEDPAGES*2 ; is object a "special" one?
- jb @@mark ; if a non-gc'ed page, must keep entry
- mov si, [(LISTDEF es:si).car.disp]
- ldpage es, bx
- mov di, [word ptype+bx] ; load type code for object
- jmp [@@table+di]
- @@list:
- test [(LISTDEF es:si).gc], GC_BIT
- jnz @@mark
- jmp @@del
- @@var:
- test [(ANYDEF es:si).gc], GC_BIT
- jnz @@mark
- @@del:
- ldpage es, [$$current.page]
- mov si, [$$current.disp]
- mov ax, [(LISTDEF es:si).cdr.disp]
- mov bl, [(LISTDEF es:si).cdr.page]
- cmp [$$previous.page], 0
- push ds
- pop es
- je @@wasinDS
- ldpage es, [$$previous.page]
- @@wasinDS:
- mov si, [$$previous.disp]
- mov [(LISTDEF es:si).car.disp], ax
- mov [(LISTDEF es:si).car.page], bl
- jmp @@loop
- @@mark:
- ldpage es, [$$pair.page]
- mov si, [$$pair.disp]
- or [(LISTDEF es:si).gc], GC_BIT
- @@skip:
- mov bx, [$$current.page]
- mov si, [$$current.disp]
- ldpage es, bx
- or [(LISTDEF es:si).gc], GC_BIT
- add si, SIZE POINTER ; this is the last valid one
- mov [$$previous.page], bx
- mov [$$previous.disp], si
- jmp @@loop
- ENDP colnext
-
- ENDP gc_oht
-
- END